/* Copyright (C) 2003, Charles Wang.
 * Author:  Charles Wang <charles@linux.net.cn>
 * All rights reserved.
 *
 * This program is free software; you can redistribute it and/or modify it
 * under the terms of the GNU General Public License as published by the Free
 * Software Foundation; either version 2, or (at your option) any later
 * version.
 *
 * This program is distributed in the hope that it will be useful, but WITHOUT
 * ANY WARRANT; without even the implied warranty of MERCHANTABILITY or FITNESS
 * FOR A PARTICULAR PURPOSE. See the GNU General Public LIcense for more
 * details.
 *
 * You should have received a copy of the GNU General Public License along
 * with this program; if not, write to the Free Software Foundation, 59 Temple
 * Place - Suite 330, Boston, MA 02111-1307, USA.
 */
#include  <stdio.h>
#include  <stdlib.h>
#include  <string.h>
#include  <newt.h>
#include  "magicbooter.h"
#include  "utils.h"
#include  "newtutils.h"
#include  "mblog.h"

extern const char * bootiso_fn;
extern const char * cdpathes[];
extern unsigned     num_cdpathes;

umnt_info  re_ui; int  re_ui_valid;

extern int check_whether_all_drvfd_loaded(void);
const char * choose_runner(void) {
    int            show_drvfd_btn;
#if !defined(NONEWT)
    newtGrid       grid, entrygrid, btngrid;
    newtComponent  form, listbox, label, entry;
    newtComponent  scsi_btn, network_btn, drvfd_btn, reboot_btn;
    newtComponent  retco;
    char labelbuf[81];
#endif
    int mi_initrd_count;
    const char    *repath;  char *iter;
    char          *userpath, *accpath = NULL;
    const char    *nextstep;

    re_ui_valid = 0;
    nextstep = NULL;

    mblog("hotfix: %s\n", mi_hotfix_fullpath);
    if (strlen(mi_hotfix_fullpath)) {
        extern int load_hotfix(void);
        load_hotfix();
    }
    mi_initrd_count = 0;
    for (repath = relist_first(&iter); repath != NULL; repath = relist_next(&iter))
        ++mi_initrd_count;

    if (mi_initrd_count > 0 && !FLAG_TEST(EXPERT)) {
        repath = relist_first(&iter);
        strcpy(mi_initrd_fullpath, repath);
        userpath = mi_initrd_fullpath;
        accpath = mount_path(userpath, &re_ui);
        if (accpath != NULL) {
            re_ui_valid = 1;
            strcpy(mi_initrd_fullpath, accpath);
            free(accpath);
            return NULL;
        }
    }

#if !defined(NONEWT)
    show_drvfd_btn = !check_whether_all_drvfd_loaded();

    grid = newtCreateGrid(1, 5);

    snprintf(labelbuf, sizeof(labelbuf), "Search for '%s' or 'miinitrd'.", bootiso_fn);
    label = newtLabel(-1, -1, labelbuf);
    newtGridSetField(grid, 0, 0, NEWT_GRID_COMPONENT, label,
                     1, 1, 1, 0, NEWT_ANCHOR_LEFT, 0);

    label = newtLabel(-1, -1, "Search Result:");
    newtGridSetField(grid, 0, 1, NEWT_GRID_COMPONENT, label,
                     1, 1, 1, 0, NEWT_ANCHOR_LEFT, 0);

    listbox = newtListbox(-1, -1, 8,
                          NEWT_FLAG_BORDER | NEWT_FLAG_SCROLL | NEWT_FLAG_RETURNEXIT);
    newtListboxSetWidth(listbox, 70);
    newtGridSetField(grid, 0, 2, NEWT_GRID_COMPONENT, listbox,
                     1, 1, 1, 0, 0, 0);

    entrygrid = newtCreateGrid(2, 1);
    label = newtLabel(-1, -1, "Position: ");
    newtGridSetField(entrygrid, 0, 0, NEWT_GRID_COMPONENT, label,
                     0, 0, 0, 0, 0, 0);
    entry = newtEntry(-1, -1, NULL, 63, NULL,
                      NEWT_FLAG_SCROLL | NEWT_FLAG_RETURNEXIT);
    newtGridSetField(entrygrid, 1, 0, NEWT_GRID_COMPONENT, entry,
                     0, 0, 0, 0, 0, 0);
    newtGridSetField(grid, 0, 3, NEWT_GRID_SUBGRID, entrygrid,
                     1, 1, 1, 0, 0, 0);

    btngrid = newtCreateGrid(show_drvfd_btn ? 4 : 3, 1);
    scsi_btn = newtButton(-1, -1, "Load SCSI driver");
    newtGridSetField(btngrid, 0, 0, NEWT_GRID_COMPONENT, scsi_btn,
                     0, 0, 0, 0, 0, 0);
    network_btn = newtButton(-1, -1, "Setup newtork");
    newtGridSetField(btngrid, 1, 0, NEWT_GRID_COMPONENT, network_btn,
                     1, 0, 0, 0, 0, 0);
    if (show_drvfd_btn) {
        drvfd_btn = newtButton(-1, -1, "Driver floppy");
        newtGridSetField(btngrid, 2, 0, NEWT_GRID_COMPONENT, drvfd_btn,
                         1, 0, 0, 0, 0, 0);
    } else
        drvfd_btn = NULL;
    reboot_btn = newtButton(-1, -1, "Reboot");
    newtGridSetField(btngrid, show_drvfd_btn ? 3 : 2, 0,
                     NEWT_GRID_COMPONENT, reboot_btn,
                     1, 0, 0, 0, 0, 0);

    newtGridSetField(grid, 0, 4, NEWT_GRID_SUBGRID, btngrid,
                     1, 1, 1, 0, 0, 0);

    form = newtExtForm(NULL, NULL, 0);
    newtGridAddComponentsToForm(grid, form, 1);

    newtGridWrappedWindow(grid, "Choose or Specify the Installer Full Image");
    newtGridFree(grid, 1);
#else                         /* NONEWT */
    printf("Search Result:\n");
#endif                        /* NONEWT */

    for (repath = relist_first(&iter); repath != NULL; repath = relist_next(&iter))
    {
#if !defined(NONEWT)
        newtListboxAppendEntry(listbox, repath, repath);
#else                         /* NONEWT */
        printf("  <%d> %s\n", mi_initrd_count, repath);
#endif
    }

    for (;;) {
#if !defined(NONEWT)
	retco = newtExtRunForm(form);
	if (retco == scsi_btn) { nextstep = "loadscsidrv";  break; }
	else if (retco == network_btn) { nextstep = "search_ether";  break; }
	else if (retco == drvfd_btn) { nextstep = "loadfloppy";  break; }
	else if (retco == reboot_btn) { nextstep = "reboot_confirm";  break; }
	else if (retco == listbox) {
	    /* The auto searched position must be local position. */
	    userpath = newtListboxGetCurrent(listbox);
#else                         /* NONEWT */
        if (mi_initrd_count != 0) {
            int sel = 0;
            if (mi_initrd_count != 1) {
                char c;
                do {
                    c = read_key("Please choose: ", '1', '0' + mi_initrd_count, '1');
                } while (!(c >= '1' && c <= '0'+mi_initrd_count));
                sel = c - '1';
            }
            for (repath = relist_first(&iter); repath != NULL && sel != 0; repath = relist_next(&iter), sel--)
                ;
            strcpy(mi_initrd_fullpath, repath);
            userpath = mi_initrd_fullpath;
#endif

	    accpath = mount_path(userpath, &re_ui);
	    if (accpath != NULL) {
		re_ui_valid = 1;
		strcpy(mi_initrd_fullpath, accpath);
		free(accpath);
		break;
	    }

#if !defined(NONEWT)
	} else if (retco == entry) {
	    char *tmp, *bn;

	    userpath = newtEntryGetValue(entry);
#else                         /* NONEWT */
        } else { /* if (mi_initrd_count == 0) */
	    char *tmp, *bn;
            int len;

            printf("No mi_initrd found!\n");
            do {
                printf("Please enter path of mi_initrd('REBOOT' to reboot): ");
                mi_initrd_fullpath[0] = '\0';
                if (fgets(mi_initrd_fullpath, sizeof(mi_initrd_fullpath), stdin) == NULL
                    || (len = strlen(mi_initrd_fullpath)) == 0)
                    continue;
                if (mi_initrd_fullpath[len-1] == '\n') {
                    mi_initrd_fullpath[len-1] = '\0';
                    len--;
                }
            } while (len == 0);
            if (!strcmp(mi_initrd_fullpath, "REBOOT")) {
                nextstep = "reboot_confirm";
                break;
            }
            userpath = mi_initrd_fullpath;
#endif
	    userpath += strspn(userpath, " \t");
	    tmp = strdupa(userpath);  bn = basename(tmp);
	    if (!strncmp(userpath, "ftp:", strlen("ftp:")) ||
		!strncmp(userpath, "http:", strlen("http:"))) {
		/* We can't mount .iso from remote server and the .iso
		   is too big to download. */
		if (!strcmp(bn, mi_initrd_file))
		    strcpy(mi_initrd_fullpath, userpath);
		else
		    snprintf(mi_initrd_fullpath, sizeof(mi_initrd_fullpath),
			     "%s/%s", userpath, mi_initrd_file);
		break;
	    }
	    if (!strcmp(bn, mi_initrd_file)) {
		accpath = mount_path(userpath, &re_ui);
		mblog("mount_path(userpath='%s') => [%s]\n", userpath, accpath);
	    } else if (!strcmp(bn, bootiso_fn)) {
		/* Try each possible position in the specified iso. */
		int  i;
		for (i = 0; i < num_cdpathes; ++i) {
		    snprintf(mi_initrd_fullpath, sizeof(mi_initrd_fullpath),
			     "%s%s/%s", userpath, cdpathes[0], mi_initrd_file);
		    accpath = mount_path(mi_initrd_fullpath, &re_ui);
		    mblog("mount_path(userpath='%s') => [%s]\n", mi_initrd_fullpath, accpath);
		    if (accpath != NULL)  break;
		}
	    } else {
		/* Try miinitrd firstly. */
		snprintf(mi_initrd_fullpath, sizeof(mi_initrd_fullpath),
			 "%s/%s", userpath, mi_initrd_file);
		accpath = mount_path(mi_initrd_fullpath, &re_ui);
		mblog("mount_path(userpath='%s') => [%s]\n", mi_initrd_fullpath, accpath);
		if (accpath == NULL) {
		    /* Try each possible possible position in .iso. */
		    int  i;
		    for (i = 0; i < num_cdpathes; ++i) {
			snprintf(mi_initrd_fullpath, sizeof(mi_initrd_fullpath),
				 "%s/%s%s/%s",
				 userpath, bootiso_fn, cdpathes[0], mi_initrd_file);
			accpath = mount_path(mi_initrd_fullpath, &re_ui);
			mblog("mount_path(userpath='%s') => [%s]\n", mi_initrd_fullpath, accpath);
			if (accpath != NULL)  break;
		    }
		}
	    }
	    if (accpath != NULL) {
		re_ui_valid = 1;
		strcpy(mi_initrd_fullpath, accpath);
		free(accpath);
		break;
	    }
	}
    }

#if !defined(NONEWT)
        newtFormDestroy(form);
        newtPopWindow();
#endif
    return  nextstep;
}
